Option Explicit On 
Option Strict Off 

'*******************************************************************
' Program: Data Center Visio Rack Tool
' Author: Albert E Edlund
' Date:
'
' Purpose: this form is the windows management interface for workstations
' and servers
'
'
' The commands necessary to create the vb.net management classes for the
' wmi data that we will provide examples for
'
' mgmtclassgen Win32_LogicalDisk /n root\cimv2 /l VB /p c:\disk.vb
' mgmtclassgen Win32_ComputerSystem /n root\cimv2 /l VB /p c:\computer.vb
' mgmtclassgen Win32_OperatingSystem /n root\cimv2 /l VB /p c:\OperatingSystem.vb
' mgmtclassgen Win32_Processor /n root\cimv2 /l VB /p c:\Processor.vb
' mgmtclassgen Win32_DiskPartition /n root\cimv2 /l VB /p c:\Partition.vb
' mgmtclassgen Win32_NetworkAdapter /n root\cimv2 /l VB /p c:\NetAdapt.vb
' mgmtclassgen Win32_NetworkAdapterConfiguration /n root\cimv2 /l VB /p c:\NetConfig.vb
' mgmtclassgen Win32_NTLogEvent /n root\cimv2 /l VB /p c:\NtLog.vb
'
'Imports System
'Imports System.Management
'Imports ROOT.CIMV2.Win32
'Public Class App
'    Public Shared Sub Main()
'        ' Enumerate instances of the Win32_process.
'        ' Print the Name property of the instance.
'        Dim ps As Process
'        For Each ps In Process.GetInstances()
'            Console.WriteLine(ps.Name)
'        Next ps

'        ' Initialize the instance of LogicalDisk with
'        ' the WMI instance pointing to logical drive d:.
'        Dim dskD As New LogicalDisk(New  _
'           ManagementPath("win32_LogicalDisk.DeviceId=""d:"""))
'        Console.WriteLine(dskD.Caption)
'    End Sub
'End Class


'*********************************************************************



Imports System
Imports System.Text

Imports Microsoft.VisualBasic
Imports System.Diagnostics
Imports WbemScripting
Imports System.Management
Imports System.Management.Instrumentation
Imports System.Windows.Forms
Imports System.Windows.Forms.Control
Imports System.Drawing
Imports System.Collections
Imports System.Runtime.InteropServices
Imports System.Reflection

Imports System.Data

Imports Microsoft.Practices.EnterpriseLibrary.Common
Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling


Imports visRackSysMgmt.WmiResults
Imports visRackSysMgmt.frmReportViewer

Public Class frmWkstMgmt
    Inherits System.Windows.Forms.Form


#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call



        With lstEventType
            .BeginUpdate()              ' hold up the updating
            .Items.Clear()              ' clear the list
            .Items.Add("Application")
            .Items.Add("Security")
            .Items.Add("System")
            .Items.Add("DNS Server")
            .Items.Add("Directory Service")
            .Items.Add("File Replication Service")
            .Items.Add("Media Center")

            .EndUpdate()                ' start the updating
            .SetSelected(2, True)

        End With





    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents TabControl1 As System.Windows.Forms.TabControl
    Friend WithEvents tbWMI_Setup As System.Windows.Forms.TabPage
    Friend WithEvents txtWMI_Workstation As System.Windows.Forms.TextBox
    Friend WithEvents txtWMI_Domain As System.Windows.Forms.TextBox
    Friend WithEvents cmdCloseWkstUtils As System.Windows.Forms.Button
    Friend WithEvents lstvwLogEvents As System.Windows.Forms.ListView
    Friend WithEvents txtWMI_UserPass As System.Windows.Forms.TextBox
    Friend WithEvents txtWMI_UserName As System.Windows.Forms.TextBox
    Friend WithEvents lblWorkstation As System.Windows.Forms.Label
    Friend WithEvents lblDomain As System.Windows.Forms.Label
    Friend WithEvents lblUserName As System.Windows.Forms.Label
    Friend WithEvents lstWmiClasses As System.Windows.Forms.ListBox
    Friend WithEvents cmdQueryWMI As System.Windows.Forms.Button
    Friend WithEvents lstEventType As System.Windows.Forms.ListBox
    Friend WithEvents StatusStrip1 As System.Windows.Forms.StatusStrip
    Friend WithEvents StatusProgress As System.Windows.Forms.ToolStripProgressBar
    Friend WithEvents StatusLabel1 As System.Windows.Forms.ToolStripStatusLabel
    Friend WithEvents StatusLabel2 As System.Windows.Forms.ToolStripStatusLabel
    Friend WithEvents lblPassword As System.Windows.Forms.Label
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.TabControl1 = New System.Windows.Forms.TabControl
        Me.tbWMI_Setup = New System.Windows.Forms.TabPage
        Me.lstEventType = New System.Windows.Forms.ListBox
        Me.cmdQueryWMI = New System.Windows.Forms.Button
        Me.lstWmiClasses = New System.Windows.Forms.ListBox
        Me.lblPassword = New System.Windows.Forms.Label
        Me.lblUserName = New System.Windows.Forms.Label
        Me.lblDomain = New System.Windows.Forms.Label
        Me.lblWorkstation = New System.Windows.Forms.Label
        Me.txtWMI_UserPass = New System.Windows.Forms.TextBox
        Me.txtWMI_UserName = New System.Windows.Forms.TextBox
        Me.txtWMI_Domain = New System.Windows.Forms.TextBox
        Me.txtWMI_Workstation = New System.Windows.Forms.TextBox
        Me.cmdCloseWkstUtils = New System.Windows.Forms.Button
        Me.StatusStrip1 = New System.Windows.Forms.StatusStrip
        Me.StatusLabel1 = New System.Windows.Forms.ToolStripStatusLabel
        Me.StatusLabel2 = New System.Windows.Forms.ToolStripStatusLabel
        Me.StatusProgress = New System.Windows.Forms.ToolStripProgressBar
        Me.TabControl1.SuspendLayout()
        Me.tbWMI_Setup.SuspendLayout()
        Me.StatusStrip1.SuspendLayout()
        Me.SuspendLayout()
        '
        'TabControl1
        '
        Me.TabControl1.Controls.Add(Me.tbWMI_Setup)
        Me.TabControl1.Location = New System.Drawing.Point(8, 8)
        Me.TabControl1.Name = "TabControl1"
        Me.TabControl1.SelectedIndex = 0
        Me.TabControl1.Size = New System.Drawing.Size(488, 364)
        Me.TabControl1.TabIndex = 0
        '
        'tbWMI_Setup
        '
        Me.tbWMI_Setup.Controls.Add(Me.lstEventType)
        Me.tbWMI_Setup.Controls.Add(Me.cmdQueryWMI)
        Me.tbWMI_Setup.Controls.Add(Me.lstWmiClasses)
        Me.tbWMI_Setup.Controls.Add(Me.lblPassword)
        Me.tbWMI_Setup.Controls.Add(Me.lblUserName)
        Me.tbWMI_Setup.Controls.Add(Me.lblDomain)
        Me.tbWMI_Setup.Controls.Add(Me.lblWorkstation)
        Me.tbWMI_Setup.Controls.Add(Me.txtWMI_UserPass)
        Me.tbWMI_Setup.Controls.Add(Me.txtWMI_UserName)
        Me.tbWMI_Setup.Controls.Add(Me.txtWMI_Domain)
        Me.tbWMI_Setup.Controls.Add(Me.txtWMI_Workstation)
        Me.tbWMI_Setup.Location = New System.Drawing.Point(4, 22)
        Me.tbWMI_Setup.Name = "tbWMI_Setup"
        Me.tbWMI_Setup.Size = New System.Drawing.Size(480, 338)
        Me.tbWMI_Setup.TabIndex = 0
        Me.tbWMI_Setup.Text = "WMI Setup"
        Me.tbWMI_Setup.UseVisualStyleBackColor = True
        '
        'lstEventType
        '
        Me.lstEventType.Enabled = False
        Me.lstEventType.FormattingEnabled = True
        Me.lstEventType.Location = New System.Drawing.Point(293, 122)
        Me.lstEventType.Name = "lstEventType"
        Me.lstEventType.Size = New System.Drawing.Size(137, 134)
        Me.lstEventType.TabIndex = 10
        '
        'cmdQueryWMI
        '
        Me.cmdQueryWMI.Location = New System.Drawing.Point(364, 280)
        Me.cmdQueryWMI.Name = "cmdQueryWMI"
        Me.cmdQueryWMI.Size = New System.Drawing.Size(104, 40)
        Me.cmdQueryWMI.TabIndex = 9
        Me.cmdQueryWMI.Text = "Query WMI/WBEM"
        '
        'lstWmiClasses
        '
        Me.lstWmiClasses.FormattingEnabled = True
        Me.lstWmiClasses.Items.AddRange(New Object() {"Win32_ComputerSystem", "Win32_Processor", "Win32_LogicalDisk", "Win32_DiskPartition", "Win32_OperatingSystem", "Win32_NetworkAdapter", "Win32_NetworkAdapterConfiguration", "Win32_NTLogEvent"})
        Me.lstWmiClasses.Location = New System.Drawing.Point(19, 122)
        Me.lstWmiClasses.Name = "lstWmiClasses"
        Me.lstWmiClasses.Size = New System.Drawing.Size(249, 134)
        Me.lstWmiClasses.TabIndex = 8
        '
        'lblPassword
        '
        Me.lblPassword.Location = New System.Drawing.Point(16, 96)
        Me.lblPassword.Name = "lblPassword"
        Me.lblPassword.Size = New System.Drawing.Size(160, 24)
        Me.lblPassword.TabIndex = 7
        Me.lblPassword.Text = "Password"
        '
        'lblUserName
        '
        Me.lblUserName.Location = New System.Drawing.Point(16, 64)
        Me.lblUserName.Name = "lblUserName"
        Me.lblUserName.Size = New System.Drawing.Size(160, 24)
        Me.lblUserName.TabIndex = 6
        Me.lblUserName.Text = "User Name"
        '
        'lblDomain
        '
        Me.lblDomain.Location = New System.Drawing.Point(16, 40)
        Me.lblDomain.Name = "lblDomain"
        Me.lblDomain.Size = New System.Drawing.Size(160, 24)
        Me.lblDomain.TabIndex = 5
        Me.lblDomain.Text = "Domain"
        '
        'lblWorkstation
        '
        Me.lblWorkstation.Location = New System.Drawing.Point(16, 16)
        Me.lblWorkstation.Name = "lblWorkstation"
        Me.lblWorkstation.Size = New System.Drawing.Size(160, 24)
        Me.lblWorkstation.TabIndex = 4
        Me.lblWorkstation.Text = "Workstation"
        '
        'txtWMI_UserPass
        '
        Me.txtWMI_UserPass.Location = New System.Drawing.Point(184, 96)
        Me.txtWMI_UserPass.Name = "txtWMI_UserPass"
        Me.txtWMI_UserPass.PasswordChar = Global.Microsoft.VisualBasic.ChrW(42)
        Me.txtWMI_UserPass.Size = New System.Drawing.Size(160, 20)
        Me.txtWMI_UserPass.TabIndex = 3
        Me.txtWMI_UserPass.Text = "Password"
        '
        'txtWMI_UserName
        '
        Me.txtWMI_UserName.Location = New System.Drawing.Point(184, 64)
        Me.txtWMI_UserName.Name = "txtWMI_UserName"
        Me.txtWMI_UserName.Size = New System.Drawing.Size(160, 20)
        Me.txtWMI_UserName.TabIndex = 2
        Me.txtWMI_UserName.Text = "Administrator"
        '
        'txtWMI_Domain
        '
        Me.txtWMI_Domain.Location = New System.Drawing.Point(184, 40)
        Me.txtWMI_Domain.Name = "txtWMI_Domain"
        Me.txtWMI_Domain.Size = New System.Drawing.Size(160, 20)
        Me.txtWMI_Domain.TabIndex = 1
        '
        'txtWMI_Workstation
        '
        Me.txtWMI_Workstation.Location = New System.Drawing.Point(184, 16)
        Me.txtWMI_Workstation.Name = "txtWMI_Workstation"
        Me.txtWMI_Workstation.Size = New System.Drawing.Size(160, 20)
        Me.txtWMI_Workstation.TabIndex = 0
        Me.txtWMI_Workstation.Text = "."
        '
        'cmdCloseWkstUtils
        '
        Me.cmdCloseWkstUtils.Location = New System.Drawing.Point(376, 378)
        Me.cmdCloseWkstUtils.Name = "cmdCloseWkstUtils"
        Me.cmdCloseWkstUtils.Size = New System.Drawing.Size(104, 40)
        Me.cmdCloseWkstUtils.TabIndex = 1
        Me.cmdCloseWkstUtils.Text = "Close Wkst Mgmt"
        '
        'StatusStrip1
        '
        Me.StatusStrip1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.StatusLabel1, Me.StatusLabel2, Me.StatusProgress})
        Me.StatusStrip1.Location = New System.Drawing.Point(0, 421)
        Me.StatusStrip1.Name = "StatusStrip1"
        Me.StatusStrip1.Size = New System.Drawing.Size(526, 22)
        Me.StatusStrip1.TabIndex = 2
        Me.StatusStrip1.Text = "StatusStrip1"
        '
        'StatusLabel1
        '
        Me.StatusLabel1.Name = "StatusLabel1"
        Me.StatusLabel1.Size = New System.Drawing.Size(0, 17)
        '
        'StatusLabel2
        '
        Me.StatusLabel2.Name = "StatusLabel2"
        Me.StatusLabel2.Size = New System.Drawing.Size(0, 17)
        '
        'StatusProgress
        '
        Me.StatusProgress.Name = "StatusProgress"
        Me.StatusProgress.Size = New System.Drawing.Size(100, 16)
        '
        'frmWkstMgmt
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(526, 443)
        Me.Controls.Add(Me.StatusStrip1)
        Me.Controls.Add(Me.cmdCloseWkstUtils)
        Me.Controls.Add(Me.TabControl1)
        Me.Name = "frmWkstMgmt"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "Server/Workstation WMI Support"
        Me.TabControl1.ResumeLayout(False)
        Me.tbWMI_Setup.ResumeLayout(False)
        Me.tbWMI_Setup.PerformLayout()
        Me.StatusStrip1.ResumeLayout(False)
        Me.StatusStrip1.PerformLayout()
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub

#End Region

#Region " Constants, Structures, Common routines "




    '
    '
    '
    Private Function funcStringFromObject(ByVal mObject As ManagementObject, _
                                    ByVal strField As String) As String
        Dim arrLocal() As String

        Dim objProperty As PropertyData = mObject.Properties(strField)

        ' it's not an array and it's not null
        If Not IsNothing(mObject(strField)) And objProperty.IsArray = False Then
            funcStringFromObject = mObject(strField).ToString()
        Else
            funcStringFromObject = ""
        End If

        ' it's an array and it's not null
        If objProperty.IsArray = True And Not IsNothing(mObject(strField)) Then
            arrLocal = objProperty.Value
            ' the array isn't null so let's just take the first entry
            funcStringFromObject = arrLocal(0)
        End If


    End Function

    '
    '
    '
    Private Function funcUpdateObjectId(ByVal strIn As String) As String
        Dim strOut As String

        If Len(strIn) = 1 Then
            strOut = "0" & strIn
        Else
            strOut = strIn
        End If

        funcUpdateObjectId = strOut

    End Function

    '
    '
    '
    Private Sub subLogManagementPath(ByVal mPath As ManagementPath)

        Dim sbManagementPath As New StringBuilder

        Try
            sbManagementPath.Append("Log management path" & vbCrLf)
            sbManagementPath.Append("Path: " + mPath.Path)
            sbManagementPath.Append("RelativePath: " + mPath.RelativePath)
            sbManagementPath.Append("Server: " + mPath.Server)
            sbManagementPath.Append("NamespacePath: " + mPath.NamespacePath)
            sbManagementPath.Append("ClassName: " + mPath.ClassName)
            'sbManagementPath.Append("IsClass: " + mPath.IsClass)
            'sbManagementPath.Append("IsInstance: " + mPath.IsInstance)
            'sbManagementPath.Append("IsSingleton: " + mPath.IsSingleton)

        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try
    End Sub

#End Region


#Region "some basics"

    '
    '
    '
    Private Function translateCimType _
        (ByVal sourceColumnType As CimType) _
        As System.Type

        Dim retSysType As System.Type = Nothing

        Try

            Select Case LCase(sourceColumnType.ToString)
                Case "sint8"
                    retSysType = Type.GetType("System.SByte")
                Case "uint8"
                    retSysType = Type.GetType("System.Byte")
                Case "sint16"
                    retSysType = Type.GetType("System.Int16")
                Case "uint16"
                    retSysType = Type.GetType("System.UInt16")
                Case "sint32"
                    retSysType = Type.GetType("System.Int32")
                Case "uint32"
                    retSysType = Type.GetType("System.UInt32")
                Case "sint64"
                    retSysType = Type.GetType("System.Int64")
                Case "uint64"
                    retSysType = Type.GetType("System.UInt64")
                Case "real32"
                    retSysType = Type.GetType("System.Single")
                Case "real64"
                    retSysType = Type.GetType("System.Double")
                Case "boolean"
                    retSysType = Type.GetType("System.Boolean")
                Case "string"
                    retSysType = Type.GetType("System.String")
                Case "datetime"
                    retSysType = Type.GetType("System.DateTime")
                Case "reference"
                    retSysType = Type.GetType("System.Int16")
                Case "object"
                    retSysType = Type.GetType("System.Object")
                Case Else
                    retSysType = Type.GetType("System.Empty")
            End Select

        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Finally
            translateCimType = retSysType
        End Try
    End Function


    '
    'A date or time value, represented in a string in DMTF date/time 
    'format: yyyymmddHHMMSS.mmmmmmsUUU, where yyyymmdd is the date in year/month/day; 
    'HHMMSS is the time in hours/minutes/seconds; 
    'mmmmmm is the number of microseconds in 6 digits; 
    'and sUUU is a sign (+ or -) and a 3-digit UTC offset. 
    'This value maps to the DateTime type.
    '
    Private Function convertCimDateTime(ByVal dmtfDate As String) _
        As DateTime
        Dim datValue As DateTime

        datValue = ManagementDateTimeConverter.ToDateTime(dmtfDate)

        Return datValue

    End Function


    '
    '
    '
    Private Sub buildCimTable(ByRef cimObject As WbemScripting.SWbemObject, _
                            ByRef m_dt As System.Data.DataTable)

        Try

            Dim wbemProps As WbemScripting.SWbemPropertySet
            Dim wbemProp As WbemScripting.SWbemProperty
            Dim objType As System.Type

            Dim m_dc As System.Data.DataColumn = New System.Data.DataColumn
            wbemProps = cimObject.Properties_
            ' if the datatable columns haven't been created then add them
            For Each wbemProp In wbemProps
                m_dc = Nothing
                m_dc = New System.Data.DataColumn
                objType = translateCimType(cimObject.Properties_.Item(wbemProp.Name).CIMType)
                m_dc.DataType = objType
                m_dc.ColumnName = wbemProp.Name
                m_dt.Columns.Add(m_dc)
            Next

        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try


    End Sub


    Private Structure stcPropertyAttributes
        Public propName As String
        Public propCimType As String
        Public propSysType As String
        Public propObjType As Collection
    End Structure

    Private colPropData As Collection = New Collection

    '
    '
    '
    Private Sub buildPropNameCol _
            (ByVal cimObject As System.Management.ManagementObject)

        Me.Cursor = Cursors.WaitCursor

        Try

            Dim cimProps As System.Management.PropertyDataCollection
            Dim cimProp As System.Management.PropertyData
            Dim objXlateType As System.Type
            Dim objcimType As System.Management.CimType
            Dim objValue As Object
            Dim strValueType As String = ""
            Dim strPropName As String
            Dim objProperties As stcPropertyAttributes
            Dim colTemp As Collection = New Collection


            Dim m_dc As System.Data.DataColumn = New System.Data.DataColumn
            cimProps = cimObject.Properties
            ' if the datatable columns haven't been created then add them
            For Each cimProp In cimProps

                strPropName = LCase(cimProp.Name)
                ' what does cim think it is
                objcimType = cimObject.Properties.Item(cimProp.Name).Type
                ' what does it translate to
                objXlateType = translateCimType(objcimType)
                Try
                    If Not (cimObject.Properties.Item(cimProp.Name).Value Is Nothing) Then
                        objValue = cimObject.Properties.Item(cimProp.Name).Value
                        strValueType = objValue.GetType.ToString
                    Else
                        strValueType = "NoObject"
                    End If
                Catch err As Exception
                End Try

                ' if property name has not been found create a new one
                ' if property name has been found check the collection
                ' of object property types and add as needed
                objProperties = Nothing
                objProperties = New stcPropertyAttributes
                If colPropData.Contains(strPropName) = False Then
                    With objProperties
                        .propName = strPropName
                        .propCimType = objcimType.ToString
                        .propSysType = objXlateType.ToString
                        .propObjType = New Collection
                        .propObjType.Add(strValueType, strValueType)
                    End With
                    Me.colPropData.Add(objProperties, strPropName)
                Else
                    objProperties = colPropData(strPropName)
                    colTemp = objProperties.propObjType
                    If colTemp.Contains(strValueType) = False Then
                        colTemp.Add(strValueType, strValueType)
                        objProperties.propObjType = colTemp
                        colPropData.Remove(strPropName)
                        colPropData.Add(objProperties, strPropName)
                    End If
                End If
            Next cimProp

        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

        Me.Cursor = Cursors.Default

    End Sub

    '
    '
    '
    Private Sub buildSmoTable(ByRef m_dt As System.Data.DataTable)

        Try

            Dim m_dc As System.Data.DataColumn = New System.Data.DataColumn
            Dim objProp As stcPropertyAttributes = New stcPropertyAttributes

            Dim objTempProp As stcPropertyAttributes = New stcPropertyAttributes
            Dim colTemp As Collection = New Collection
            Dim strProp As String = ""
            Dim intPropCt As Integer = 0
            Dim strPropName As String = ""
            Dim strTemp As String = ""


            ' first clear up the collection of property types

            For Each objProp In colPropData
                strPropName = objProp.propName
                ' clear out the our null record pointers
                If objProp.propObjType.Contains("NoObject") Then
                    objTempProp = Nothing
                    objTempProp = New stcPropertyAttributes
                    objTempProp = objProp
                    colTemp = Nothing
                    colTemp = New Collection
                    colTemp = objProp.propObjType
                    colTemp.Remove("NoObject")
                    objTempProp.propObjType = colTemp
                    colPropData.Remove(strPropName)
                    colPropData.Add(objTempProp, strPropName)
                End If
            Next


            For Each objProp In colPropData

                strPropName = objProp.propName

                m_dc = Nothing
                m_dc = New System.Data.DataColumn
                m_dc.ColumnName = strPropName


                If 1 = colPropData(strPropName).propObjType.Count Then
                    ' make a string of the collection
                    strProp = BuildCsvString(objProp.propObjType)
                    If InStr(strProp, "[]") Then
                        ' we will handle arrays as csv strings
                        m_dc.DataType = Type.GetType("System.String")
                    Else
                        m_dc.DataType = Type.GetType(objProp.propSysType)
                    End If
                End If

                Try
                    m_dt.Columns.Add(m_dc)
                Catch err As Exception
                    Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
                End Try
            Next


        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub


    '
    '
    '
    Private Sub buildCimRecord(ByRef cimObject As WbemScripting.SWbemObject, _
                               ByRef m_dr As System.Data.DataRow)

        Try

            Dim wbemProps As WbemScripting.SWbemPropertySet
            Dim wbemProp As WbemScripting.SWbemProperty
            Dim objType As System.Type
            Dim objCimType As CimType

            wbemProps = cimObject.Properties_
            Dim objValue As Object
            For Each wbemProp In wbemProps
                objCimType = cimObject.Properties_.Item(wbemProp.Name).CIMType
                objType = translateCimType(objCimType)
                If Not IsNothing(cimObject.Properties_.Item(wbemProp.Name).Value) Then
                    objValue = cimObject.Properties_.Item(wbemProp.Name).Value
                    Try
                        If objType.ToString = "System.DateTime" Then
                            m_dr.Item(wbemProp.Name) = ManagementDateTimeConverter.ToDateTime(objValue)
                        Else
                            m_dr.Item(wbemProp.Name) = objValue
                        End If
                    Catch err As Exception
                        ' log it and move on 
                        ExceptionPolicy.HandleException(err, "Log Only Policy")
                    End Try
                Else
                    Select Case objType.ToString
                        Case "System.String"
                            m_dr.Item(wbemProp.Name) = ""
                        Case "System.Boolean"
                            m_dr.Item(wbemProp.Name) = False
                        Case "System.DateTime"
                            m_dr.Item(wbemProp.Name) = #1/1/2001#
                        Case Else
                            m_dr.Item(wbemProp.Name) = 0
                    End Select
                End If
            Next wbemProp

        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try

    End Sub

    '
    '
    '
    Private Sub buildSmoRecord(ByRef cimObject As System.Management.ManagementObject, _
                            ByRef m_dr As System.Data.DataRow)
        Try

            Dim cimProps As System.Management.PropertyDataCollection
            Dim cimProp As System.Management.PropertyData
            Dim objType As System.Type
            Dim objXlateType As System.Type
            Dim objCimType As CimType
            Dim objValue As Object

            Dim m_dc As System.Data.DataColumn = New System.Data.DataColumn
            cimProps = cimObject.Properties
            ' if the datatable columns haven't been created then add them
            Dim strPropName As String
            For Each cimProp In cimProps
                strPropName = LCase(cimProp.Name)
                objCimType = cimObject.Properties.Item(cimProp.Name).Type
                objXlateType = translateCimType(objCimType)
                If Not IsNothing(cimObject.Properties.Item(cimProp.Name).Value) Then
                    objValue = cimObject.Properties.Item(cimProp.Name).Value
                    objType = objValue.GetType
                    Try
                        ' have to handle date time different
                        If objXlateType.ToString = "System.DateTime" Then
                            m_dr.Item(strPropName) = ManagementDateTimeConverter.ToDateTime(objValue)
                            GoTo NextProp
                        End If

                        If objType.IsArray = True Then
                            m_dr.Item(strPropName) = objValue.ToString
                        Else
                            m_dr.Item(strPropName) = objValue
                        End If

                    Catch err As Exception
                        ' log it and move on 
                        ExceptionPolicy.HandleException(err, "Log Only Policy")
                    End Try
                Else
                    Select Case objXlateType.ToString
                        Case "System.String"
                            m_dr.Item(strPropName) = ""
                        Case "System.Boolean"
                            m_dr.Item(strPropName) = False
                        Case "System.DateTime"
                            m_dr.Item(strPropName) = #1/1/2001#
                        Case Else
                            m_dr.Item(strPropName) = 0
                    End Select
                End If
NextProp:
            Next cimProp


        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        End Try


    End Sub


    '
    '
    '
    Public Function queryWMI_Data(ByVal strClassName As String, _
                Optional ByVal strOptional As String = "") _
                As System.Data.DataTable

        Dim strComputer As String = ""
        Dim strDomain As String = ""
        Dim strUserName As String = ""
        Dim strUserPass As String = ""
        Dim strNameSpace As String = "root\cimv2"
        Dim strLocale As String = "ms_409"
        Dim m_dt As System.Data.DataTable = New DataTable

        Try
            ' domain name can be required for remote when different than local
            strDomain = txtWMI_Domain.Text
            strUserName = txtWMI_UserName.Text
            If strDomain <> "" Then
                strUserName = strDomain & "\" & strUserName
            End If

            strUserPass = txtWMI_UserPass.Text
            strComputer = txtWMI_Workstation.Text

            ' if target is blank do the local
            If strComputer = "" Then strComputer = "."

            ' Build a connection options object
            Dim cOptions As New ConnectionOptions
            cOptions.Username = strUserName
            cOptions.Password = txtWMI_UserPass.Text
            cOptions.Authentication = AuthenticationLevel.PacketPrivacy
            cOptions.Impersonation = ImpersonationLevel.Impersonate
            cOptions.Locale = strLocale

            Dim eOptions As New EnumerationOptions
            eOptions.EnumerateDeep = False
            eOptions.ReturnImmediately = False
            eOptions.Rewindable = False

            Dim mPath As New ManagementPath
            With mPath
                .Server = strComputer
                .NamespacePath = strNameSpace
                .ClassName = strClassName
            End With

            Dim mScope As New ManagementScope
            With mScope
                .Path = mPath
                If strComputer <> "." Then
                    .Options = cOptions
                End If
            End With

            ' build query
            Dim mQuery As SelectQuery
            If strOptional = "" Then
                mQuery = New SelectQuery("SELECT * FROM " & strClassName)
            Else
                mQuery = New SelectQuery(strOptional)
            End If

            ' build searcher
            StatusLabel1.Text = "Begin Object DownLoad"
            Dim mSearcher As New ManagementObjectSearcher(mScope, mQuery)
            Dim m_dr As DataRow = Nothing

            Dim cimCollection As System.Management.ManagementObjectCollection = mSearcher.Get
            Dim intCount As Integer = cimCollection.Count
            Dim intPos As Integer = 0
            Dim dblDone As Double = 0
            Dim dblMod As Double = 0
            StatusProgress.Minimum = 0
            StatusProgress.Maximum = 100
            StatusLabel1.Text = "Begin Processing Records"
            ' clear the properties collection
            If colPropData Is Nothing Then
                Me.colPropData = New Collection
            Else
                colPropData = Nothing
                colPropData = New Collection
            End If
            ' this is overkill but given the need for accuracy
            ' we bite the bullet
            For Each cimObject In cimCollection
                buildPropNameCol(cimObject)
                dblMod = intPos Mod 10
                If dblMod = 0 Then
                    dblDone = (intPos / intCount * 100)
                    StatusProgress.Value = dblDone
                    StatusLabel2.Text = intPos & " of " & intCount
                End If
                intPos = intPos + 1
            Next cimObject
            StatusProgress.Value = 0

            ' now that we have built the collection of properties
            ' test them
            buildSmoTable(m_dt)

            For Each cimObject In mSearcher.Get()
                m_dr = m_dt.NewRow
                buildSmoRecord(cimObject, m_dr)
                m_dt.Rows.Add(m_dr)
            Next cimObject


        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
        Finally
            StatusLabel1.Text = ""
            StatusLabel2.Text = ""
            queryWMI_Data = m_dt
        End Try

    End Function

    '
    '
    '
    Private Sub buildReport(ByVal intReport As Integer, _
                            ByVal dtReport As System.Data.DataTable)

        Dim frmExport As visRackSysMgmt.frmReportViewer = New visRackSysMgmt.frmReportViewer(intReport, dtReport)
        frmExport.ShowDialog()
        frmExport.Dispose()
        frmExport = Nothing

    End Sub


    '
    '
    '
    Private Function funcQueryComputerRole _
                        (ByRef wbemServices As WbemScripting.SWbemServices, _
                        ByRef lngInstanceFlags As Integer) _
                        As String

        Dim strClass As String
        Dim sbOutput As New StringBuilder
        Dim strDomainRole As String
        Dim wbemObjectSet As WbemScripting.SWbemObjectSet
        Dim wbemObject As WbemScripting.SWbemObject

        Dim intArrayCtr As Short

        Try
            sbOutput.Length = 0

            strClass = "Win32_ComputerSystem"
            sbOutput.Append(vbCrLf & vbCrLf & strClass)

            ' we could probably do this with instances but want to keep the query format
            wbemObjectSet = wbemServices.ExecQuery("Select * from Win32_ComputerSystem")
            For Each wbemObject In wbemObjectSet
                With wbemObject

                    sbOutput.Append(vbCrLf & "System Name = " & .Name)
                    sbOutput.Append(vbCrLf & "CurUserName = " & .UserName)
                    ' sbOutput.append(vbCrLf & "System Mem  = " & .TotalPhysicalMemory
                    sbOutput.Append(vbCrLf & "Domain Name = " & .Domain)
                    Select Case .DomainRole
                        Case 0
                            strDomainRole = "Standalone Workstation"
                        Case 1
                            strDomainRole = "Member Workstation"
                        Case 2
                            strDomainRole = "Standalone Server"
                        Case 3
                            strDomainRole = "Member Server"
                        Case 4
                            strDomainRole = "Backup Domain Controller"
                        Case 5
                            strDomainRole = "Primary Domain Controller"
                        Case Else
                            strDomainRole = "Unknown"
                    End Select

                    sbOutput.Append(vbCrLf & "Domain Role = " & strDomainRole & vbCrLf)

                    intArrayCtr = UBound(.roles)
                    For intArrayCtr = 0 To UBound(.roles)
                        sbOutput.Append(vbCrLf & "Potential Role = " & .roles(intArrayCtr))
                    Next intArrayCtr

                End With

            Next wbemObject

            Return sbOutput.ToString

        Catch err As Exception
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
            Return ""
        End Try

    End Function



#End Region




#Region " Event Handlers "

    '
    '
    '
    Private Sub cmdCloseWkstUtils_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCloseWkstUtils.Click
        Me.Close()
    End Sub

    '
    '
    '
    Private Sub cmdQueryWMI_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdQueryWMI.Click

        Dim m_dt As System.Data.DataTable = New System.Data.DataTable
        Dim intReport As Integer = -1
        Dim strSelect As String = lstWmiClasses.SelectedItem
        Dim strQuery As String = ""
        Dim strLogFile As String = ""

        Select Case strSelect
            Case "Win32_Processor"
                intReport = visRackSysMgmt.clsDC_RackReporting.baseReports.rptWmiProcessor
                m_dt = queryWMI_Data(strSelect)
            Case "Win32_LogicalDisk"
                intReport = visRackSysMgmt.clsDC_RackReporting.baseReports.rptWmiLogicalDisks
                m_dt = queryWMI_Data(strSelect)
            Case "Win32_OperatingSystem"
                intReport = visRackSysMgmt.clsDC_RackReporting.baseReports.rptWmiOperatingSystem
                m_dt = queryWMI_Data(strSelect)
            Case "Win32_ComputerSystem"
                intReport = visRackSysMgmt.clsDC_RackReporting.baseReports.rptWmiComputerSystem
                m_dt = queryWMI_Data(strSelect)
            Case "Win32_DiskPartition"
                intReport = visRackSysMgmt.clsDC_RackReporting.baseReports.rptWmiDiskPartition
                m_dt = queryWMI_Data(strSelect)
            Case "Win32_NetworkAdapter"
                intReport = visRackSysMgmt.clsDC_RackReporting.baseReports.rptWmiNetworkAdapter
                m_dt = queryWMI_Data(strSelect)
            Case "Win32_NetworkAdapterConfiguration"
                intReport = visRackSysMgmt.clsDC_RackReporting.baseReports.rptWmiNetworkAdapterConfiguration
                m_dt = queryWMI_Data(strSelect)
            Case "Win32_NTLogEvent"
                If lstEventType.SelectedItems.Count <> 0 Then
                    strLogFile = lstEventType.SelectedItem.ToString
                    intReport = visRackSysMgmt.clsDC_RackReporting.baseReports.rptWmiNtLogEvent
                    strQuery = "SELECT * FROM Win32_NTLogEvent WHERE Logfile = '" & strLogFile & "'"

                    Dim resultMsg As MsgBoxResult

                    resultMsg = MsgBox("EventLogs can take a lot of time, Continue?", MsgBoxStyle.OkCancel, "Extended Query")
                    If resultMsg <> MsgBoxResult.Ok Then
                        Exit Sub
                    End If
                    m_dt = queryWMI_Data(Me.lstWmiClasses.SelectedItem, strQuery)
                Else
                    MsgBox("Have to select an log type first")
                    lstEventType.SetSelected(0, True)
                End If
        End Select

        buildReport(intReport, m_dt)

    End Sub

    '
    '
    '
    Private Sub lstWmiClasses_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstWmiClasses.Click


        If lstWmiClasses.SelectedItem.ToString = "Win32_NTLogEvent" Then
            Me.lstEventType.Enabled = True
        Else
            Me.lstEventType.Enabled = False
        End If


    End Sub


#End Region


    '
    ' create a csv string with end brackets from a collection
    '
    Private Function BuildCsvString _
        (ByVal colA As Collection) _
        As String

        Dim intY As Integer
        Dim strCsv As String = "[]"
        Try

            If (colA Is Nothing) _
                Or (colA.Count = 0) Then
                Exit Try
            Else
                With colA
                    ' start bracket
                    strCsv = "["
                    For intY = 1 To colA.Count
                        strCsv = strCsv & CStr(colA.Item(intY))
                        If intY <> colA.Count Then
                            strCsv = strCsv & ","
                        End If ' test for last position
                    Next intY
                    ' end bracket
                    strCsv = strCsv & "]"
                End With
            End If

        Catch ex As Exception
            '********* visio snippet vb.net visXXXX ******************
            Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "Log Only Policy")
            If (rethrow) Then
                Throw
            End If
            strCsv = "[]"
        End Try

        BuildCsvString = strCsv

    End Function



End Class
